﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;

namespace Founder.PKURG.CRM
{
    public class CRMInfoOP
    {
        private string prefix;

        public string Prefix
        {
            get { return prefix; }
            set { prefix = value + "_"; }
        }


        Microsoft.Xrm.Sdk.IOrganizationService service;

        public CRMInfoOP()
        {
            connect = new CRM.AdminCrmConnect();
            connect.ConnectionString = "isIFD=false;UserName=administrator;Password=Founder@123;Domain=test;OrgServiceUri=http://172.25.20.82/TestCRM/XRMServices/2011/Organization.svc";
            service = connect.OrgService;
        }

        public Founder.PKURG.CRM.AdminCrmConnect connect;

        public CRMInfoOP(string connection)
        {
             connect= new CRM.AdminCrmConnect();
            connect.ConnectionString = connection;
            service = connect.OrgService;
        }

        public CRMInfoOP(IOrganizationService _service)
        {
            service = _service;
        }

        #region 实体记录操作

        public Guid Add(CRMInfo info)
        {
            //有异常直接抛出
            //try
            //{
            if (info != null)
            {
                Microsoft.Xrm.Sdk.Entity entity = new Microsoft.Xrm.Sdk.Entity(info.Name);
                foreach (FieldInfo item in info.Fields)
                {
                    if ((item.IsForeign || !string.IsNullOrEmpty(item.ForeignName)
                        && new Guid(item.Value.ToString()) != Guid.Empty))
                    {
                        entity[item.Name] = new EntityReference(item.ForeignName, new Guid(item.Value.ToString()));
                    }
                    else
                    {
                        entity[item.Name] = item.Value;
                    }
                }

                Guid id = service.Create(entity);
                if (id.ToString() != "" && id.ToString() != "00000000-0000-0000-0000-000000000000")
                {
                    return id;
                }

            }
            return Guid.Empty;
            //}
            //catch (Exception ex)
            //{
            //    LoggerWorker.logger.DebugFormat("Ex--AddProject:{0}\r\n{1}", ex.Message, ex.StackTrace);
            //    return Guid.Empty;
            //}
        }

        public bool Update(CRMInfo info)
        {
            if (info != null)
            {
                Microsoft.Xrm.Sdk.Entity entity = new Microsoft.Xrm.Sdk.Entity(info.Name);
                entity[info.PrimaryField.Name] = info.PrimaryField.Value;
                foreach (FieldInfo item in info.Fields)
                {
                    if ((item.IsForeign || !string.IsNullOrEmpty(item.ForeignName)
                        && new Guid(item.Value.ToString()) != Guid.Empty))
                    {
                        entity[item.Name] = new EntityReference(item.ForeignName, new Guid(item.Value.ToString()));
                    }
                    else
                    {
                        entity[item.Name] = item.Value;
                    }
                }

                service.Update(entity);
                return true;
            }
            return false;
        }

        public void Delete(string infoName, Guid primary)
        {
            service.Delete(infoName, primary);
        }

        #endregion

        #region 实体创建

        public void CreateEntity(EntityInfo info)
        {
            CreateEntityRequest createrequest = new CreateEntityRequest
            {

                //Define the entity
                Entity = new EntityMetadata
                {
                    SchemaName = prefix + info.SchemaName,
                    DisplayName = new Label(info.DisplayName, 2052),
                    DisplayCollectionName = new Label(info.DisplayName, 2052),
                    //Description = new Label("An entity to store information about customer bank accounts", 1033),
                    OwnershipType = OwnershipTypes.UserOwned,
                    IsActivity = false,

                },

                // Define the primary attribute for the entity
                PrimaryAttribute = new StringAttributeMetadata
                {
                    SchemaName = prefix + "name",
                    RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                    MaxLength = 100,
                    Format = StringFormat.Text,
                    DisplayName = new Label("名称", 2052),
                    //Description = new Label("The primary attribute for the Bank Account entity.", 1033)
                }
            };
            service.Execute(createrequest);
        }

        public void CreateEntityFields(string entityName, EntityInfoField info)
        {
            CreateAttributeRequest createAttributeRequest = new CreateAttributeRequest
            {
                EntityName = prefix + entityName.ToLower()
            };
            if (info.SchemaName.ToLower()=="name")
            {
                info.SchemaName = "custom_name";
            }

            AttributeMetadata attr = null;
            switch (info.FType)
            {
                case EntityInfoFieldType.IntType:
                    attr = new IntegerAttributeMetadata()
                  {
                      SchemaName = prefix + info.SchemaName,
                      RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                      DisplayName = new Label(info.DisplayName, 2052)
                  };
                    break;
                case EntityInfoFieldType.FloatType:
                    attr = new DecimalAttributeMetadata()
                    {
                        SchemaName = prefix + info.SchemaName,
                        Precision = 2,
                        RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                        DisplayName = new Label(info.DisplayName, 2052)
                    };
                    break;
                case EntityInfoFieldType.TextType:
                    attr = new StringAttributeMetadata()
                    {
                        SchemaName = prefix + info.SchemaName,
                        RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                        DisplayName = new Label(info.DisplayName, 2052),
                         MaxLength=100
                    };
                    break;
                case EntityInfoFieldType.DateTimeType:
                    attr = new DateTimeAttributeMetadata()
                    {
                        SchemaName = prefix + info.SchemaName,
                        RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                        DisplayName = new Label(info.DisplayName, 2052)
                    };
                    break;
                //case EntityInfoFieldType.GuidType:
                //    attr = new LookupAttributeMetadata()
                //    {
                //        SchemaName = prefix + info.SchemaName,
                //        RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                //        DisplayName = new Label(info.DisplayName, 2052),

                //    };
                //    break;
                default:
                    break;
            }

            createAttributeRequest.Attribute = attr;

            service.Execute(createAttributeRequest);
        }

        public void CreateEntityLookField(string entityName,string beRefEntityName,string beRefAttrName, EntityInfoField info)
        {
            //CreateAttributeRequest createAttributeRequest = new CreateAttributeRequest
            //{
            //    EntityName = prefix + entityName.ToLower()
            //};
            //AttributeMetadata attr = null;
            beRefEntityName = beRefEntityName.ToLower();
            beRefAttrName = beRefAttrName.ToLower();
            entityName = entityName.ToLower();

            CreateOneToManyRequest createAttributeRequest = new CreateOneToManyRequest()
            {
                Lookup = new LookupAttributeMetadata()
                {
                    //Description = new Label("The owner of the bank account", 1033),
                    SchemaName = prefix + info.SchemaName,
                    RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.ApplicationRequired),
                    DisplayName = new Label(info.DisplayName, 2052),
                    //LogicalName = "new_parent_contactid"
                },
                OneToManyRelationship = new OneToManyRelationshipMetadata()
                {
                    AssociatedMenuConfiguration = new AssociatedMenuConfiguration()
                    {
                        Behavior = AssociatedMenuBehavior.UseCollectionName,
                        Group = AssociatedMenuGroup.Details,
                        Label = new Label(info.DisplayName, 2052),
                       // Order = 10000
                    },
                    CascadeConfiguration = new CascadeConfiguration()
                    {
                        Assign = CascadeType.Cascade,
                        Delete = CascadeType.Cascade,
                        Merge = CascadeType.Cascade,
                        Reparent = CascadeType.Cascade,
                        Share = CascadeType.Cascade,
                        Unshare = CascadeType.Cascade
                    },
                    ReferencedEntity = prefix + beRefEntityName,
                    ReferencedAttribute = prefix + (beRefAttrName.ToLower()=="id"?beRefEntityName+"id":beRefAttrName),
                    ReferencingEntity = prefix + entityName,
                    SchemaName = string.Format("{0}_{1}_{0}_{2}",prefix,beRefEntityName,entityName)
                }
            };

            service.Execute(createAttributeRequest);
        }

        #endregion
    }
}
